<template>
  <div>
    <div style="text-align: center">
      <h3>意向岗位</h3>
    </div>
    <div
      class="wordCloud__tagBall"
      :style="{ width: `${this.width}px`, height: `${this.height}px` }"
      @mouseenter="stop"
      @mouseleave="start"
    >
      <span
        class="wordCloud__tag"
        v-for="(item, index) of data"
        :key="index"
        :style="{ color: color[index % color.length], ...contentEle[index].style }"
        :title="item.name + item.value"
        >{{ item.name }}</span
      >
    </div>
  </div>
</template>

<script>
export default {
  name: "cloudWork",
  props: {
    width: {
      type: Number,
      default: 300,
    },
    height: {
      type: Number,
      default: 250,
    },
    // 测试数据
    data: {
      type: Array,
      default: () => [
        {
          name: "Java开发工程师",
          value: 3000,
        },
        {
          name: "测试工程师",
          value: 30,
        },
        {
          name: "架构工程师",
          value: 80,
        },
        {
          name: "前端专员",
          value: 30,
        },
        {
          name: "后端开发",
          value: 30,
        },
        {
          name: "自主研发",
          value: 30,
        },
        {
          name: "产品经理",
          value: 30,
        },
        {
          name: "招聘专员",
          value: 30,
        },
      ],
    },
  },
  data: () => ({
    color: ["#2D4DB6", "#04B67C", "#D1AF07", "#E27914", "#CB4A4D", "#B02690"],
    contentEle: [],
    direction: "-1",
    speed: 400,
    animateID: null,
  }),
  created() {
    this.contentEle = this.data.map(() => ({
      x: 0,
      y: 0,
      z: 0,
      style: {},
    }));
  },
  mounted() {
    this.innit();
  },
  methods: {
    innit() {
      const RADIUSX = (this.width - 50) / 2;
      const RADIUSY = (this.height - 50) / 2;
      this.contentEle = [];
      for (let i = 0; i < this.data.length; i += 1) {
        const k = -1 + (2 * (i + 1) - 1) / this.data.length;
        const a = Math.acos(k);
        const b = a * Math.sqrt(this.data.length * Math.PI);
        const x = RADIUSX * Math.sin(a) * Math.cos(b);
        const y = RADIUSY * Math.sin(a) * Math.sin(b);
        const z = RADIUSX * Math.cos(a);
        const singleEle = {
          x,
          y,
          z,
          style: {},
        };
        this.contentEle.push(singleEle);
      }
      this.animate();
    },
    animate() {
      this.rotateX();
      this.rotateY();
      this.move();
      this.animateID = window.requestAnimationFrame(this.animate);
    },
    rotateX() {
      const angleX = ["-1", "1"].includes(this.direction)
        ? Math.PI / Infinity
        : Math.PI / ((Number(this.direction) / 2) * Number(this.speed));
      const cos = Math.cos(angleX);
      const sin = Math.sin(angleX);

      this.contentEle = this.contentEle.map((t) => {
        const y1 = t.y * cos - t.z * sin;
        const z1 = t.z * cos + t.y * sin;
        return {
          ...t,
          y: y1,
          z: z1,
        };
      });
    },
    rotateY() {
      const angleY = ["-2", "2"].includes(this.direction)
        ? Math.PI / Infinity
        : Math.PI / (Number(this.direction) * Number(this.speed));
      const cos = Math.cos(angleY);
      const sin = Math.sin(angleY);
      this.contentEle = this.contentEle.map((t) => {
        const x1 = t.x * cos - t.z * sin;
        const z1 = t.z * cos + t.x * sin;
        return {
          ...t,
          x: x1,
          z: z1,
        };
      });
    },
    move() {
      const CX = this.width / 2;
      const CY = this.height / 2;
      this.contentEle = this.contentEle.map((singleEle) => {
        const { x, y, z } = singleEle;
        const fallLength = 500;
        const RADIUS = (this.width - 50) / 2;
        const scale = fallLength / (fallLength - z);
        const alpha = (z + RADIUS) / (2 * RADIUS);
        const left = `${x + CX - 15}px`;
        const top = `${y + CY - 15}px`;
        const transform = `translate(${left}, ${top}) scale(${scale})`;
        const style = {
          ...singleEle.style,
          opacity: alpha + 0.5,
          zIndex: parseInt(scale * 100, 10),
          transform,
        };
        return {
          x,
          y,
          z,
          style,
        };
      });
    },
    // 鼠标移入暂停
    stop() {
      window.cancelAnimationFrame(this.animateID);
    },
    // 鼠标离开恢复
    start() {
      this.animate();
    },
  },
};
</script>

<style scoped>
button {
  margin: 30px;
}
.wordCloud__tagBall {
  margin-top: 10px;
  margin-bottom: 65px;
  /* margin: 25px auto; */
  position: relative;
}

.wordCloud__tag {
  display: block;
  position: absolute;
  left: 0px;
  top: 0px;
  color: green;
  text-decoration: none;
  font-size: 15px;
  font-family: "微软雅黑";
  font-weight: bold;
}
.wordCloud__tag :hover {
  color: red;
}

.wordCloud__home {
  display: flex;
  justify-content: center;
}
</style>
